package eerbaar.shared.internal.tree;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import eerbaar.shared.tree.IAttribute;
import eerbaar.shared.tree.IAttributes;

public class AttributesImpl implements IAttributes {

    private final Map<String, IAttribute<?>> map = new HashMap<String, IAttribute<?>>();

    public AttributesImpl() {
        //
    }

    public AttributesImpl(IAttributes attributes) {

        Iterator<IAttribute<Object>> i = attributes.iterator();
        while (i.hasNext()) {
            IAttribute<?> a = i.next();
            this.map.put(a.getKey(), a);
        }
    }

    @Override
    public IAttributes copy() {
        return new AttributesImpl(this);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T get(Class<T> type, String key) {
        assert (type != null);
        assert (key != null);

        IAttribute<?> attribute = this.map.get(key);

        if (attribute == null) {
            return null;
        }

        if (type.getName().equals("java.lang.Integer")) {
            int n = Integer.parseInt(attribute.getValue().toString());
            return (T) new Integer(n);
        }
        if (type.getName().equals("java.lang.String")) {
            return (T) attribute.getValue().toString();
        }

        return (T) attribute.getValue();
    }

    @Override
    public IAttribute<?> get(String key) {
        return this.map.get(key);
    }

    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Iterator iterator() {

        return this.map.values().iterator();
    }

    @Override
    public <T> void set(Class<T> type, String key, T value) {

        IAttribute<T> attribute;

        if (value == null) {
            attribute = new NullAttribute<T>(key, type);
        } else {
            attribute = new Attribute<T>(type, value, key);
        }

        this.map.put(key, attribute);
    }

    @Override
    public String toString() {

        StringBuilder s = new StringBuilder();

        Set<String> set = this.map.keySet();
        Iterator<String> i = set.iterator();
        while (i.hasNext()) {

            String key = i.next();
            if (key.startsWith("private")) {
                continue;
            }

            if (s.length() > 0) {
                s.append(", ");
            }

            Object obj = this.map.get(key);
            s.append(key);
            s.append("=");
            s.append(obj);
        }

        return "{" + s.toString() + "}";
    }

}
